﻿using Cube.Data;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CubeForm.AI
{
    class FirstLayer : IPattenMatch
    {
        Cube.Data.Cube cube;
        PattenManager patten;
        List<PositionVector> Angles = new List<PositionVector>
        {
            new PositionVector(1, 1, 1),
            new PositionVector(1, -1, 1),
            new PositionVector(-1, 1, 1),
            new PositionVector(-1, -1, 1),
            new PositionVector(1, 1, -1),
            new PositionVector(1, -1, -1),
            new PositionVector(-1, 1, -1),
            new PositionVector(-1, -1, -1)
        };

        public event PattenMatchedDelegate PattenMatched;

        public FirstLayer(Cube.Data.Cube cube)
        {
            this.cube = cube;
            patten = new PattenManager(cube);
        }

        public void Invoke()
        {
            for(var i = 0; i < 4; i++)
            {
                var groove_colors = GetGrooveColors();
                var groove_vector = new ColorVector(groove_colors[0], groove_colors[1], groove_colors[2]);
                foreach(var angle in Angles)
                {
                    if (!cube[angle].Equals(groove_vector)) continue;
                    var selected_index = cube.FindCubeByPosition(angle);
                    var selected_block = cube[selected_index];
                    Debug.WriteLine("Origin Position:" + selected_block.Position.X + "," + selected_block.Position.Y + "," + selected_block.Position.Z);
                    ParaseToBrainlessCase(selected_block.Position);
                    Debug.WriteLine("Parased Position:" + selected_block.Position.X + "," + selected_block.Position.Y + "," + selected_block.Position.Z);
                    while (!CheckBrainlessResult())
                    //for(var j=0;j<8;j++)
                    {
                        Debug.WriteLine("In NC Loop:(gole: 1,1,-1 " + groove_colors[2] + "," + groove_colors[1] + "," + groove_colors[0] + ")");
                        DoBrainlessPatten();
                        Debug.WriteLine("Check:" + CheckBrainlessResult());
                        Debug.WriteLine("\tPosition:" + selected_block.Position.X + "," + selected_block.Position.Y + "," + selected_block.Position.Z);
                        Debug.WriteLine("\tColor:" + selected_block.ColorVector.X + "," + selected_block.ColorVector.Y + "," + selected_block.ColorVector.Z + "\n");
                    }
                }
                patten.y();
            }
            PattenMatched?.Invoke(patten.GetRecord());
        }

        /// <summary>
        /// 转一次脑残公式
        /// </summary>
        private void DoBrainlessPatten()
        {
            patten.R();
            patten.U();
            patten._R();
            patten._U();
        }

        /// <summary>
        /// 获取围成"槽"的三个颜色
        /// </summary>
        /// <returns></returns>
        private CubeColor[] GetGrooveColors()
        {
            var result = new CubeColor[]
            {
                cube[new PositionVector(0,0,-1)].Z,
                cube[new PositionVector(0,1,0)].Y,
                cube[new PositionVector(1,0,0)].X
            };
            return result;
        }

        /// <summary>
        /// 转化为脑残公式适用的情况
        /// </summary>
        private void ParaseToBrainlessCase(PositionVector position)
        {
            if(position.Equals(new PositionVector(1, -1, 1)))
            {
                patten.U();
            }
            if(position.Equals(new PositionVector(-1, 1, 1)))
            {
                patten._U();
            }
            if(position.Equals(new PositionVector(-1, -1, 1)))
            {
                patten.U(); patten.U();
            }
            if (position.Equals(new PositionVector(1, -1, -1)))
            {
                patten._R(); patten.U(); patten.U(); patten.R(); patten._U();
            }
            if (position.Equals(new PositionVector(-1, 1, -1)))
            {
                patten.F(); patten.U(); patten.U(); patten._F(); patten.U();
            }
            if (position.Equals(new PositionVector(-1, -1, -1)))
            {
                patten.L(); patten.U(); patten.U(); patten._L();
            }
        }

        /// <summary>
        /// 检查是否还原到正确位置
        /// </summary>
        /// <returns></returns>
        private bool CheckBrainlessResult()
        {
            var correct_block = cube[new PositionVector(1, 1, -1)];
            if(correct_block.Z== cube[new PositionVector(0, 0, -1)].Z &&
                correct_block.Y== cube[new PositionVector(0, 1, 0)].Y &&
                correct_block.X== cube[new PositionVector(1, 0, 0)].X)
            {
                return true;
            }
            return false;
        }
    }
}
